﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using Microsoft.AnalysisServices;
using Microsoft.SqlServer.Management;

namespace SSMS_Scripter
{
    /// <summary>
    /// User control listing objects and processing modes, for use with cubes and dimensions
    /// </summary>
    public partial class ProcessList : UserControl
    {
        #region Fields

        // List of objects available to configure
        List<string> objects;

        // True if processing dims, false if processing cubes
        bool processDim;

        // Link back to parent menu item (which holds connection, context information)
        MenuItem parent;

        // Starting name width (for expanding column sizing
        int baseNameWidth=-1;

        // Internal field controlling select all / none
        bool selectAll = true;

        #endregion

        #region Constructors
        public ProcessList()
        {
            InitializeComponent();
        }

        public ProcessList(List<string> _objects, bool _processDim, MenuItem _parent)
            : this()
        {
            LoadControl(_objects, _processDim, _parent);
        }
        #endregion

        /// <summary>
        /// Initializes data, interface for user control
        /// </summary>
        /// <param name="_objects"></param>
        /// <param name="_processDim"></param>
        /// <param name="_parent"></param>
        public void LoadControl(List<string> _objects, bool _processDim, MenuItem _parent)
        {
            objects = _objects;
            processDim = _processDim;
            parent = _parent;

            // Create data table
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("include", typeof(Boolean)));
            dt.Columns.Add(new DataColumn("name", typeof(string)));
            dt.Columns.Add(new DataColumn("processType", typeof(string)));

            // Assign processing options
            ((DataGridViewComboBoxColumn)dgvProcess.Columns["ProcessOption"]).DataSource = 
                    cmbProcessOption.DataSource = GetProcessOptions(_processDim);
            cmbProcessOption.SelectedItem = "ProcessDefault";

            // Fill data table
            DataRow dr;
            foreach (string s in objects)
            {
                dr = dt.NewRow();
                dr["include"] = true;
                dr["name"] = s;
                dr["processType"] = "ProcessDefault";
                dt.Rows.Add(dr);
            }
            dgvProcess.DataSource = dt;
            baseNameWidth = dgvProcess.Width - dgvProcess.Columns["objectName"].Width;

            ProcessList_Resize(null, null);
        }

        /// <summary>
        /// Generates list of processing modes, based on cube or dimension
        /// </summary>
        /// <param name="dimension"></param>
        /// <returns></returns>
        private List<string> GetProcessOptions(bool dimension)
        {
            List<string> result = new List<string>();

            result.Add(ProcessType.ProcessClear.ToString());
            result.Add(ProcessType.ProcessData.ToString());
            result.Add(ProcessType.ProcessDefault.ToString());
            result.Add(ProcessType.ProcessFull.ToString());
            result.Add(ProcessType.ProcessIndexes.ToString());
            if (dimension)
            {
                result.Add(ProcessType.ProcessUpdate.ToString());
                result.Add(ProcessType.ProcessAdd.ToString());
            }
            else
            {
                result.Add(ProcessType.ProcessScriptCache.ToString());
                result.Add(ProcessType.ProcessStructure.ToString());
            }

            result.Sort();

            return result;
        }

        /// <summary>
        /// Generates final query based on selection and processing type
        /// </summary>
        /// <returns></returns>
        public string GetQuery()
        {
            string result="";
            foreach(DataRow dr in ((DataTable)dgvProcess.DataSource).Rows)
            {
                if((bool)dr["include"])
                    if (processDim)
                        result += parent.dimProcess.Replace("@Database", parent.database).Replace("@Dim", (string)dr["name"])
                                .Replace("ProcessFull", (string)dr["processType"]);
                    else
                        result += parent.cubeProcess.Replace("@Database", parent.database).Replace("@Cube", (string)dr["name"])
                                .Replace("ProcessFull", (string)dr["processType"]);
            }

            return result;
        }

        /// <summary>
        /// Resizes name column
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ProcessList_Resize(object sender, EventArgs e)
        {
            if(baseNameWidth > 0)
                dgvProcess.Columns["objectName"].Width = dgvProcess.Width - baseNameWidth;
        }

        /// <summary>
        /// Applies currently selected processing mode to all selected rows
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnApply_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < dgvProcess.SelectedRows.Count; i++ )
                dgvProcess.SelectedRows[i].Cells["ProcessOption"].Value = cmbProcessOption.SelectedValue;
        }

        /// <summary>
        /// Handles clicking on the header, which selects all/none
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvProcess_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (dgvProcess.Columns[e.ColumnIndex].Name.ToLower() == "include")
            {
                // Select all / none
                foreach (DataGridViewRow r in dgvProcess.Rows)
                {
                    DataGridViewCheckBoxCell c = (DataGridViewCheckBoxCell)r.Cells["include"];
                    if (selectAll)
                        c.Value = false;
                    else
                        c.Value = true;
                }
                dgvProcess.Columns["include"].HeaderText = (selectAll ? "All" : "None");

                selectAll = !selectAll;
            }
        }
    }
}
